import sys, urllib, urllib2, re, cookielib, string, simplejson

class RedirectHandler(urllib2.HTTPRedirectHandler):
	def http_error_301(self, req, fp, code, msg, headers):  
		return str(headers)

	def http_error_302(self, req, fp, code, msg, headers):
		return str(headers) 
	
class DailymotionCore(object):
	__settings__ = sys.modules[ "__main__" ].__settings__
	__language__ = sys.modules[ "__main__" ].__language__
	__plugin__ = sys.modules[ "__main__" ].__plugin__	
	__dbg__ = sys.modules[ "__main__" ].__dbg__			

	KEY = "43bdaecd3ac615df909b"
	SECRET = "604c4ad68790295d342faec90572febdd511de19"
	USERAGENT = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8"

	#===============================================================================
	#
	# External functions called by YouTubeNavigation.py
	#
	# return MUST be a tupple of ( result[string or dict], status[int] )
	#
	#===============================================================================
	
	def __init__(self):
		if self.__dbg__:
			print self.__plugin__ + " __init__ " 
		#self.v = vimeo.VimeoClient()
		self.oauth_token = self.__settings__.getSetting("oauth_token")
		self.oauth_token_secret = self.__settings__.getSetting("oauth_token_secret")
		
		if ( self.oauth_token and self.oauth_token_secret ):
			self.v.__init__(token = self.oauth_token, token_secret = self.oauth_token_secret)
		
	def interrogate(self, item):
		"""Print useful information about item."""
		if hasattr(item, '__name__'):
			print "NAME:	", item.__name__
		if hasattr(item, '__class__'):
			print "CLASS:   ", item.__class__.__name__
		print "ID:	  ", id(item)
		print "TYPE:	", type(item)
		print "VALUE:   ", repr(item)
		print "CALLABLE:",
		if callable(item):
			print "Yes"
		else:
			print "No"

		if hasattr(item, '__doc__'):
			doc = getattr(item, '__doc__')
			if doc:
				doc = doc.strip()
				firstline = doc.split('\n')[0]
				print "DOC:	 ", firstline

	def login(self):
		login_values = {'accepted_scope[]':'delete',
				'dm_username':self.__settings__.getSetting("user_name"),
				'dm_password':self.__settings__.getSetting("user_password"),
				'accept':'Accept'}
		
		#STEP 1: hit authorization url
		postdata = urllib.urlencode(login_values)
		opener = urllib2.build_opener(RedirectHandler)
		link1 = "https://api.dailymotion.com/oauth/authorize?response_type=code&client_id="+ self.KEY +"&redirect_uri=http://www.xbmc.org"
		request = urllib2.Request(link1,postdata)
		request.add_header('Content-Type','application/x-www-form-urlencoded')
		request.add_header('User-Agent', self.USERAGENT)
		urllib2.install_opener(opener)
	
		#extract authorization_code from redirect header
		code = urllib2.urlopen(request)
		if code.find("code=") > 0:
			code = code[code.find("code=") + 5:]
			code = code[:code.find("&scope=")]
		else:
			print self.__plugin__ + " login: Failed to get authorization_code from dailymotion, is the password correct?"
			return ( self.__language__(30609), 303) 
		
		#STEP 2: request access token
		link2 = "https://api.dailymotion.com/oauth/token"
		authorization_values= ([("grant_type","authorization_code"),
							("client_id",self.KEY),
							("client_secret",self.SECRET),
							("redirect_uri","http://www.xbmc.org"),
							("code",code)])
		postdata2 = urllib.urlencode(authorization_values)
	
		request2 = urllib2.Request(link2,postdata2)
		request2.add_header('Content-Type','application/x-www-form-urlencoded')
		request2.add_header('User-Agent', self.USERAGENT)
		urllib2.install_opener(opener)
		response = urllib2.urlopen(request2)
		
		#parse json_response
		json_response = response.read()
		tmp = simplejson.loads(json_response)
		get = tmp.get
		
		access_token = get("access_token","")
		refresh_token = get("refresh_token","")
		uid = get("uid","")
		
		if not access_token:
			return (self.__language__(30609), 303 )		
		else:
			self.__settings__.setSetting("userid", uid)
			self.__settings__.setSetting("access_token", access_token)
			self.__settings__.setSetting("refresh_token", access_token)
			
		return (self.__language__(30030), 200 )
					

	def downloadVideo(self, video):
		if self.__dbg__:
			print self.__plugin__ + " downloadVideo : " + video['Title']
		
		path = self.__settings__.getSetting( "downloadPath" )
		try:
			url = urllib2.Request(video['video_url'])
			url.add_header('User-Agent', self.USERAGENT);
			valid_chars = "-_.() %s%s" % (string.ascii_letters, string.digits)
			
			filename = "%s/%s.mp4" % ( path, ''.join(c for c in video['Title'] if c in valid_chars) )
			file = open(filename, "wb")
			con = urllib2.urlopen(url);
			file.write(con.read())
			con.close()
				
			self.__settings__.setSetting( "vidstatus-" + video['videoid'], "1" )
		except urllib2.HTTPError, e:
			if self.__dbg__:
				print self.__plugin__ + " downloadVideo except: " + str(e)
			return ( str(e), 303 )
		except:
			if self.__dbg__:
				print self.__plugin__ + " downloadVideo uncaught exception"
				print 'ERROR: %s::%s (%d) - %s' % (self.__class__.__name__, sys.exc_info()[2].tb_frame.f_code.co_name, sys.exc_info()[2].tb_lineno, sys.exc_info()[1])
				
			return (self.__language__(30606), 303)

		if self.__dbg__:
			print self.__plugin__ + " downloadVideo done"
		return ( video, 200 )
	
	def setLike(self, params):
		if self.__dbg__:
			print self.__plugin__ + " setLike "
			
		get = params.get
		
		if (get("action") == "add_favorite"): 
			print "temp"
			#result = self.v.vimeo_videos_setLike(like = "true", video_id=get("videoid"), oauth_token=self.oauth_token)
		else:
			print "other temp"
			#result = self.v.vimeo_videos_setLike(like = "false", video_id=get("videoid"), oauth_token=self.oauth_token)

		if self.__dbg__:
			print self.__plugin__ + " setLike done"
				
		return self._get_return_status(result)
	
	def updateContact(self, params):
		if self.__dbg__:
			print self.__plugin__ + " updateContact"

		get = params.get
		
		if (get("action") == "add_contact"): 
			print "temp"
			#result = self.v.vimeo_people_addContact(user_id=get("contact"), oauth_token=self.oauth_token)
		else:
			print "other temp"
			#result = self.v.vimeo_people_removeContact(user_id=get("contact"), oauth_token=self.oauth_token)

		if self.__dbg__:
			print self.__plugin__ + " updateContact done"
				
		return self._get_return_status(result)

	def addToWatchLater(self, params):
		if self.__dbg__:
			print self.__plugin__ + " addToWatchLater"
		get = params.get
		
		#result = self.v.vimeo_albums_addToWatchLater(video_id = get("videoid") )
		
		return self._get_return_status(result)
		
	def removeWatchLater(self, params):
		if self.__dbg__:
			print self.__plugin__ + " removeFromWatchLater"
		get = params.get
		
		#result = self.v.vimeo_albums_removeFromWatchLater(video_id = get("videoid"))
		
		return self._get_return_status(result) 
		
	def updateGroup(self, params):
		if self.__dbg__:
			print self.__plugin__ + " updateGroup"

		get = params.get
		
		if (get("action") == "join_group"): 
			print "other"
			#result = self.v.vimeo_groups_join(group_id=get("group"), oauth_token=self.oauth_token)
		else:
			print "something"
			#result = self.v.vimeo_groups_leave(group_id=get("group"), oauth_token=self.oauth_token)

		if self.__dbg__:
			print self.__plugin__ + " updateGroup done"
				
		return self._get_return_status(result)

	def updateSubscription(self, params):
		if self.__dbg__:
			print self.__plugin__ + " updateSubscription"
				
		get = params.get

		if (get("action") == "add_subscription"): 
			print "kom"
			#result = self.	channels_subscribe(channel_id=get("channel"), oauth_token=self.oauth_token)
		else:
			print "fko"
			#result = self.v.vimeo_channels_unsubscribe(channel_id=get("channel"), oauth_token=self.oauth_token)

		if self.__dbg__:
			print self.__plugin__ + " updateSubscription done"
				
		return self._get_return_status(result)
	
	def construct_video_url(self, videoid, encoding = 'utf-8'):
		if self.__dbg__:
			print self.__plugin__ + " construct_video_url : " + repr(videoid)
			
		video = self._get_details(videoid)
		if not video:
			if self.__dbg__:
				print self.__plugin__ + " construct_video_url failed because of missing video from _get_details"
			return ("", 500)
		
		hd_quality = int(self.__settings__.getSetting( "hd_videos" ))
		
		
		url = urllib2.Request("http://www.dailymotion.com/video/%s" % videoid)
		url.add_header('User-Agent', self.USERAGENT)
		
		con = urllib2.urlopen(url);
		value = con.read()	
		con.close()
					
		if value.find('%22videoPluginParameters') > 0:
			print self.__plugin__ + " standard video"
			urls = value[value.find('%22videoPluginParameters%22%3A') + 30 :]
			urls = urls[:urls.find('%7D%7D%2C') + 3]
			urls = urllib.unquote_plus(urls)
			value = simplejson.loads(urls)
			get = value.get
			
			if (hd_quality):
				video["video_url"] = get("hdURL","")
				
			if (not video["video_url"]):
				if (get("hqURL","")):
					video["video_url"] = get("hqURL","")
				else:
					video["video_url"] = get("sdURL","")
				
			if self.__dbg__: 
				print self.__plugin__ + " construct_video_url done: "# + repr(video)
					
			return ( video, 200 )
		elif value.find("dmpi_video_partnerplayer") > 0:
			print self.__plugin__ + " partner_player"
			token = value[value.find("new SWFObject("):]
			token = token[token.find("content=") + 9:]
			token = token[:token.find('",')]
			print self.__plugin__ + " token " + token
			
			if (token):
				url = "http://content.grabnetworks.com/v/%s?from=www.dailymotion.com" % token
				request = urllib2.Request(url)
				print self.__plugin__ + " url: " + url
				request.add_header('User-Agent', self.USERAGENT)
				con = urllib2.urlopen(request)
				value = con.read()
				con.close()
				json = simplejson.loads(value)

				if (json["video"]["media"]["stream"]["low"]):
					video["video_url"] = json["video"]["media"]["stream"]["low"]["url"]
			return ( video, 200 )
		else:
			if self.__dbg__:
				print self.__plugin__ + " construct_video_url, unknown error"
			return ("", 303)
	
	def search(self, query, page = "0"):
		if self.__dbg__:
			print self.__plugin__ + " search: " + repr(query)
		
		per_page = ( 10, 15, 20, 25, 30, 40, 50, )[ int( self.__settings__.getSetting( "perpage" ) ) ]
		
		args = {}
		args["search"] = query
		args["limit"] = per_page
		args["sort"] = "relevance"
		args["page"] = int(page) + 1
		args["fields"] = ("id", "title", "channel", "description", "duration", "created_time", "owner", "thumbnail_url", "thumbnail_small_url", "thumbnail_medium_url", "thumbnail_large_url", "rating", "views_total")
		info = {}
		info["call"] = "video.list"
		info["args"] = args
		json_query = simplejson.dumps(info)
		
		query = urllib2.Request("https://api.dailymotion.com/json", json_query)
		query.add_header("Content-Type", "application/json")
		query.add_header('User-Agent', self.USERAGENT)
		answer = urllib2.urlopen(query).read()
		
		result = []

		result = self._getvideoinfo(answer);
		
		if result:
			if self.__dbg__:
				print self.__plugin__ + " search done :" + str(len(result))
			return (result, 200)
		else:
			if self.__dbg__:
				print self.__plugin__ + " search done with no results"
			return (self.__language__(30601), 303)

	def listVideoFeed(self, params):
		if self.__dbg__:
			print self.__plugin__ + " listVideoFeed"
				
		get = params.get
		
		page = int(get("page","0")) + 1
		per_page = ( 10, 15, 20, 25, 30, 40, 50, )[ int( self.__settings__.getSetting( "perpage" ) ) ]

		if (get("channel")):
			print "ko"
			#result = self.v.vimeo_channels_getVideos(channel_id=get("channel"), page=page, per_page=per_page, full_response="true")
		elif (get("album")):
			print "kom"
			#result = self.v.vimeo_albums_getVideos(album_id=get("album"), page=page, per_page=per_page, full_response="true")
		elif (get("group")):
			print "kom"		
			#result = self.v.vimeo_groups_getVideos(group_id=get("group"), page=page, per_page=per_page, full_response="true")

		if (not result):
			if self.__dbg__:
				print self.__plugin__ + " listVideoFeed result was empty"
			return (result, 303)
		else:
			result = self._getvideoinfo(result);

		if self.__dbg__:
			print self.__plugin__ + " listVideoFeed done"
				
		return ( result, 200 )
	
	def getUserData(self, params):
		if self.__dbg__:
			print self.__plugin__ + " getUserData"

		get = params.get

		page = int(get("page", "0")) + 1
		per_page = ( 10, 15, 20, 25, 30, 40, 50, )[ int( self.__settings__.getSetting( "perpage" ) ) ]
		
		user_id = self.__settings__.getSetting("userid")

		if (get("external")):
			user_id = get("contact")
		
		if self.__dbg__:
			print self.__plugin__ + " calling vimeo api for " + get("api") + " with user_id: " + repr(user_id) + " page: " + repr(page) + " per_page: " + repr(per_page)
		'''
		if (get("api") == "my_videos"):
			result = self.v.vimeo_videos_getAll(user_id=user_id, per_page=per_page, page=page, full_response="true")
			result = self._getvideoinfo(result)  
		elif (get("api") == "my_likes"):
			result = self.v.vimeo_videos_getLikes(user_id=user_id, per_page=per_page, page=page, full_response="true")
			result = self._getvideoinfo(result)
		elif (get("api") == "my_watch_later" and not get("external")):
			result = self.v.vimeo_albums_getWatchLater(per_page=per_page, page=page, full_response="true")
			result = self._getvideoinfo(result)
		elif (get("api") == "my_newsubscriptions"):
			result = self.v.vimeo_videos_getSubscriptions(user_id=user_id, per_page=per_page, page=page, full_response="true", sort="newest")
			result = self._getvideoinfo(result)
		elif (get("api") == "my_albums"):	 
			result = self.v.vimeo_albums_getAll(user_id =user_id, per_page=per_page, page=page, full_response="true")
			result = self._get_list('album', result)
		elif (get("api") == "my_groups"):
			result = self.v.vimeo_groups_getAll(user_id = user_id, per_page=per_page, page=page, full_response="true")
			result = self._get_list('group', result)
		elif (get("api") == "my_channels"):
			result = self.v.vimeo_channels_getAll(user_id = user_id, per_page=per_page, page=page, full_response="true")
			result = self._get_list('channel', result)
		elif (get("api") == "my_contacts"):
			result = self.v.vimeo_contacts_getAll(user_id = user_id, per_page=per_page, page=page, full_response="true")
			result = self._get_contacts(result)
			'''
		result = ""
		if (not result):
			if self.__dbg__:
				print self.__plugin__ + " getUserData result was empty"
					
			return (self.__language__(30602), 303)

		if self.__dbg__:
			print self.__plugin__ + " getUserData done"
				
		return (result, 200) 

	def _get_return_status(self, result):
		if self.__dbg__:
			print self.__plugin__ + " _get_return_status "
		
		xml = BeautifulStoneSoup(result)
		
		result = [];
		if (len(xml) > 0):
			stat = xml.rsp["stat"]
			if stat == "ok":
				return ( result, 200 )
			elif stat == "fail":
				message = xml.rsp.err["message"]
				if self.__dbg__:
					print self.__plugin__ + " _get_return_status fail: " + repr(message)
						
				return ( message, 303 )
			else:
				return ( "", 500 )
		else:
			if self.__dbg__:
				print self.__plugin__ + " _get_return_status invalid response xml from vimeo api"
		
		return ( "No response from Vimeo API", 303 )
																
	def _get_details(self, videoid):
		if self.__dbg__:
			print self.__plugin__ + " _get_details: " + repr(videoid)	
		
		args = {}
		args["id"] = videoid
		args["fields"] = ("title", "id", "duration", "owner", "description", "thumbnail_url", "thumbnail_small_url", "thumbnail_medium_url", "thumbnail_large_url")
		info = {}
		info["call"] = "video.info"
		info["args"] = args
		json_query = simplejson.dumps(info)
		
		query = urllib2.Request("https://api.dailymotion.com/json", json_query)
		query.add_header("Content-Type", "application/json")
		query.add_header('User-Agent', self.USERAGENT)
		answer = urllib2.urlopen(query).read()
		
		result = []
		
		if (len(answer) > 10):
			video = {}
			if self.__dbg__:
				print self.__plugin__ + " dailymotion api answer: " + repr(answer)
				
			json = simplejson.loads(answer)
			get = json.get
			if (json["result"]):
				get = json["result"].get
			
			video["videoid"] = get("id","")
			video["Title"] = get("title","")
			video['Duration'] = get("duration","")
			video["thumbnail"] = get("thumbnail_large_url","")
			video["Studio"] = get("owner","")
			
			if self.__dbg__:
				print self.__plugin__ + " resulting video object: " #+ repr(video)
			result.append(video)
		
		if len(result) == 0:
			if self.__dbg__:
				print self.__plugin__ + " _get_details result was empty"
			return False
		else:
			if self.__dbg__:
				print self.__plugin__ + " _get_details done"
			return result[0];
		
	def _get_list(self, tag, result):
		if self.__dbg__:
			print self.__plugin__ + " _get_list: "
		
		xml = BeautifulStoneSoup(result)
		item = xml.find(name=tag)
		next = "false"
		
		result = [];

		while item != None:
			group = {}
			title = ""
			if (item.find(name="name") != None):
				ti = item.find(name="name")
				title = ti.contents[0]
			else:
				title = item.title.contents[0]
			
			title = title.replace("&amp;", "&")
			title = title.replace("&quot;", '"')
			title = title.replace("&hellip;", "...")
			
			group[tag] = item["id"]
			group['Title'] = title
			
			if (item.description != None):
				group['Description'] = item.description.contents[0]
			
			if (tag == "group"):
				group["thumbnail"] = item.logo_url.contents[0]
			if (tag == "album"):
				group["thumbnail"] = self.getThumbnail(item, "default") 
			if (tag == "channel"):
				thumbnail = ""
				if (item.badge_url != None and item.badge_url.contents[0].rfind("default") == -1):
					thumbnail = item.badge_url.contents[0]
				
				if (not thumbnail):
					if (item.logo_url != None and item.logo_url.contents[0].rfind("default") == -1):
						thumbnail = item.logo_url.contents[0]
					else:
						thumbnail = "default"
				group["thumbnail"] = thumbnail

			result.append(group)
			
			item = item.findNextSibling(name=tag)
					
		if len(result) == 0:
			if self.__dbg__:
				print self.__plugin__ + " _get_list result was empty"
			return False
		else:				
			if self.__dbg__:
				print self.__plugin__ + " _get_list done"
			return result;
	
	def _get_contacts(self, result):
		if self.__dbg__:
			print self.__plugin__ + " _get_contacts: " + result
			
		xml = BeautifulStoneSoup(result)
		contact = xml.contacts.contact
		next = "false"
		
		result = [];
		
		while contact != None:
			group = {}
			group['contact'] = contact["id"]
			group['Title'] = contact['display_name']
			
			portrait = contact.portraits.portrait
			while (portrait != None):
				
				width = portrait["width"]
				if (int(width) <= 300):
					group['thumbnail'] = portrait.contents[0]
				
				portrait = portrait.findNextSibling(name="portrait")
			result.append(group)
			contact = contact.findNextSibling(name="contact")
					
		if len(result) == 0:
			if self.__dbg__:
				print self.__plugin__ + " _get_contacts result was empty"
			return False
		else:				
			if self.__dbg__:
				print self.__plugin__ + " _get_contacts done"
			return result;

	def _getvideoinfo(self, value):
		if self.__dbg__:
			print self.__plugin__ + " _getvideoinfo: " + str(len(value))
		vobjects = [];
		
		json = simplejson.loads(value)
		
		if (json["result"]):
			
			next = "false"
			if (json["result"].get("has_more")):
				next = "true"
			 
			for entry in json["result"]["list"]:
				video = {}
				video['videoid'] = entry["id"]
				video['Title'] = entry["title"]
				video['Plot'] = entry["description"]
				video['Studio'] = entry["owner"]
				video['contact'] = entry["owner"]
				video['channel'] = entry["channel"]
				duration = int(entry["duration"])
				video['Duration'] = "%02d:%02d" % ( duration / 60, duration % 60 ) 
				#video['rating'] = entry["rating"]
				video['views'] = str(entry["views_total"])
				video['thumbnail'] = self.getThumbnail(entry, "default")
				video["next"] = next
				overlay = self.__settings__.getSetting( "vidstatus-" + video['videoid'] )
				if overlay:
					video['Overlay'] = int(overlay)
				
				vobjects.append(video)
			
		if self.__dbg__:
			print self.__plugin__ + " _get_videoinfo done " + repr(vobjects)
			
		return vobjects
	
	def getThumbnail(self, item, default = "default"):
		thumb = item.get
		
		if (thumb("thumbnail_large_url","")):
			default = thumb("thumbnail_large_url","")
		else:
			if (thumb("thumbnail_medium_url","")):
				default = thumb("thumbnail_medium_url","")
			else:
				if (thumb("thumbnail_small_url","")):
					default = thumb("thumbnail_small_url","")
				else:
					if (thumb("thumbnail_url","")):
						default = thumb("thumbnail_url","")		
		return default

